home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
mint104s.zoo
/
mint.src
/
util.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-08
|
13KB
|
641 lines
/*
Copyright 1990,1991,1992 Eric R. Smith.
Copyright 1992 Atari Corporation.
All rights reserved.
*/
/*
* misc. utility routines
*/
#include "mint.h"
/*
* given an address, find the corresponding memory region in this program's
* memory map
*/
MEMREGION *
addr2mem(a)
virtaddr a;
{
int i;
for (i = 0; i < curproc->num_reg; i++) {
if (a == curproc->addr[i])
return curproc->mem[i];
}
return 0;
}
/*
* given a pid, return the corresponding process
*/
PROC *
pid2proc(pid)
int pid;
{
PROC *p;
for (p = proclist; p; p = p->gl_next) {
if (p->pid == pid)
return p;
}
return 0;
}
/*
* return a new pid
*/
int
newpid()
{
static int _maxpid = 1;
int i;
#ifndef NDEBUG
int j = 0;
#endif
do {
i = _maxpid++;
if (_maxpid >= 1000) _maxpid = 1;
assert(j++ < 1000);
} while (pid2proc(i));
return i;
}
/*
* zero out a block of memory, quickly; the block must be word-aligned,
* and should be long-aligned for speed reasons
*/
void
zero(place, size)
char *place;
long size;
{
long cruft;
cruft = size % 256; /* quickzero does 256 byte blocks */
size = size / 256;
while (cruft > 0) {
*place++ = 0;
cruft--;
}
if (size > 0) {
quickzero(place, size);
}
}
#ifdef JUNK_MEM
void
fillwjunk(place, size)
long *place;
long size;
{
while (size > 0) {
*place++ = size;
size -= 4;
}
}
#endif
/*
* kernel memory allocation routines
*/
#define KERMEM_THRESHOLD QUANTUM-8
#define KMAGIC ((MEMREGION *)0x87654321L)
#define NKMAGIC 0x19870425L
void * ARGS_ON_STACK
kmalloc(size)
long size;
{
MEMREGION *m = 0;
MEMREGION **p;
long *lp;
/*
* increase size by two pointers' worth: the first contains
* a pointer to the region descriptor for this block, and the
* second contains KMAGIC. If the block came from nalloc,
* then they both contain NKMAGIC.
*/
size += sizeof(m) + sizeof(m);
/*
* for small requests, we use nalloc first
*/
tryagain:
if (size < KERMEM_THRESHOLD) {
lp = nalloc(size);
if (lp) {
*lp++ = NKMAGIC;
*lp++ = NKMAGIC;
TRACELOW(("kmalloc(%lx) -> (nalloc) %lx",size,lp));
return lp;
}
else {
DEBUG(("kmalloc(%lx): nalloc is out of memory",size));
/* If this is commented out, then we fall through to try_getregion */
if (0 == (m = get_region(alt, QUANTUM, PROT_S))) {
if (0 == (m = get_region(core, QUANTUM, PROT_S))) {
DEBUG(("No memory for another arena"));
goto try_getregion;
}
}
nalloc_arena_add((void *)m->loc,QUANTUM);
m = 0;
goto tryagain;
}
}
try_getregion:
m = get_region(alt, size, PROT_S);
if (!m) m = get_region(core, size, PROT_S);
if (m) {
p = (MEMREGION **)m->loc;
*p++ = KMAGIC;
*p++ = m;
TRACELOW(("kmalloc(%lx) -> (get_region) %lx",size,p));
return (void *)p;
}
else {
TRACELOW(("kmalloc(%lx) -> (fail)",size));
#if 0
/* this is a serious offense; I want to hear about it */
/* maybe Allan wanted to hear about it, but ordinary users
* won't! -- ERS
*/
NALLOC_DUMP();
BIG_MEM_DUMP(0,0);
#endif
return 0;
}
}
/* allocate from ST memory only */
void *
kcore(size)
long size;
{
MEMREGION *m;
MEMREGION **p;
size += sizeof(m) + sizeof (m);
m = get_region(core, size, PROT_S);
if (m) {
p = (MEMREGION **)m->loc;
*p++ = KMAGIC;
*p++ = m;
return (void *)p;
}
else {
return 0;
}
}
void ARGS_ON_STACK
kfree(place)
void *place;
{
MEMREGION **p;
MEMREGION *m;
TRACELOW(("kfree(%lx)",place));
if (!place) return;
p = place;
p -= 2;
if (*p == (MEMREGION *)NKMAGIC) {
nfree(p);
return;
}
else if (*p++ != KMAGIC) {
FATAL("kfree: memory not allocated by kmalloc");
}
m = *p;
if (--m->links != 0) {
FATAL("kfree: block has %d links", m->links);
}
free_region(m);
}
/*
* "user" memory allocation routines; the kernel can use these to
* allocate/free memory that will be attached in some way to a process
* (and freed automatically when the process exits)
*/
void * ARGS_ON_STACK
umalloc(size)
long size;
{
return (void *)m_xalloc(size, 3);
}
void ARGS_ON_STACK
ufree(block)
void *block;
{
(void)m_free((virtaddr)block);
}
/*
* convert a time in milliseconds to a GEMDOS style date/time
* timeptr[0] gets the time, timeptr[1] the date.
* BUG/FEATURE: in the conversion, it is assumed that all months have
* 30 days and all years have 360 days.
*/
void ARGS_ON_STACK
ms_time(ms, timeptr)
ulong ms;
short *timeptr;
{
ulong secs;
short tsec, tmin, thour;
short tday, tmonth, tyear;
secs = ms / 1000;
tsec = secs % 60;
secs /= 60; /* secs now contains # of minutes */
tmin = secs % 60;
secs /= 60; /* secs now contains # of hours */
thour = secs % 24;
secs /= 24; /* secs now contains # of days */
tday = secs % 30;
secs /= 30;
tmonth = secs % 12;
tyear = secs / 12;
*timeptr++ = (thour << 11) | (tmin << 5) | (tsec >> 1);
*timeptr = (tyear << 9) | ((tmonth + 1) << 5) | (tday+1);
}
/*
* unixtim(time, date): convert a Dos style (time, date) pair into
* a Unix time (seconds from midnight Jan 1., 1970)
*/
static int
mth_start[13] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 };
long ARGS_ON_STACK
unixtim(time, date)
unsigned time, date;
{
int sec, min, hour;
int mday, mon, year;
long y, s;
sec = (time & 31) << 1;
min = (time >> 5) & 63;
hour = (time >> 11) & 31;
mday = date & 31;
mon = ((date >> 5) & 15) - 1;
year = 80 + ((date >> 9) & 255);
/* calculate tm_yday here */
y = (mday - 1) + mth_start[mon] + /* leap year correction */
( ( (year % 4) != 0 ) ? 0 : (mon > 1) );
s = (sec) + (min * 60L) + (hour * 3600L) +
(y * 86400L) + ((year - 70) * 31536000L) +
((year - 69)/4) * 86400L;
return s;
}
/* convert a Unix time into a DOS time. The longword returned contains
the time word first, then the date word.
BUG: we completely ignore any time zone information.
*/
#define SECS_PER_MIN (60L)
#define SECS_PER_HOUR (3600L)
#define SECS_PER_DAY (86400L)
#define SECS_PER_YEAR (31536000L)
#define SECS_PER_LEAPYEAR (SECS_PER_DAY + SECS_PER_YEAR)
static int
days_per_mth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
long ARGS_ON_STACK
dostim(t)
long t;
{
unsigned long time, date;
int tm_hour, tm_min, tm_sec;
int tm_year, tm_mon, tm_mday;
int i;
if (t <= 0) return 0;
tm_year = 70;
while (t >= SECS_PER_YEAR) {
if ((tm_year & 0x3) == 0) {
if (t < SECS_PER_LEAPYEAR)
break;
t -= SECS_PER_LEAPYEAR;
} else {
t -= SECS_PER_YEAR;
}
tm_year++;
}
tm_mday = (int)(t/SECS_PER_DAY);
days_per_mth[1] = (tm_year & 0x3) ? 28 : 29;
for (i = 0; tm_mday >= days_per_mth[i]; i++)
tm_mday -= days_per_mth[i];
tm_mon = i+1;
tm_mday++;
t = t % SECS_PER_DAY;
tm_hour = (int)(t/SECS_PER_HOUR);
t = t % SECS_PER_HOUR;
tm_min = (int)(t/SECS_PER_MIN);
tm_sec = (int)(t % SECS_PER_MIN);
if (tm_year < 80) {
tm_year = 80;
tm_mon = tm_mday = 1;
tm_hour = tm_min = tm_sec = 0;
}
time = (tm_hour << 11) | (tm_min << 5) | (tm_sec >> 1);
date = ((tm_year - 80) & 0x7f) << 9;
date |= ((tm_mon) << 5) | (tm_mday);
return (time << 16) | date;
}
/*
* Case insensitive string comparison. note that this only returns
* 0 (match) or nonzero (no match), and that the returned value
* is not a reliable indicator of any "order".
*/
int ARGS_ON_STACK
strnicmp(str1, str2, len)
register const char *str1, *str2;
register int len;
{
register char c1, c2;
do {
c1 = *str1++; if (isupper(c1)) c1 = tolower(c1);
c2 = *str2++; if (isupper(c2)) c2 = tolower(c2);
} while (--len >= 0 && c1 && c1 == c2);
if (len < 0 || c1 == c2)
return 0;
return c1 - c2;
}
int ARGS_ON_STACK
stricmp(str1, str2)
const char *str1, *str2;
{
return strnicmp(str1, str2, 0x7fff);
}
/*
* string utilities: strlwr() conv